﻿namespace DangerousRiver
{
    using System;

    class Menu
    {
        private static int windowWidth = 60;
        private static int windowHeight = 30;
        private static int currentItem = 0;
        private static bool isChoiceMade = false;
        private static string menuTitle = "Dangerous river";
        private static string[] menuItems = { "New Game", "Highscores", "Credits", "Exit Game" };   // Store menu options

        /// <summary>
        /// Print menu title.
        /// </summary>
        /// <param name="name">Menu title.</param>
        private static void PrintMenuTitle(string name)
        {
            // TO DO: [Optional] Draw the title name as a Logo. Change the method if the feature is released.
            Console.SetCursorPosition((windowWidth - name.Length) / 2, 10);
            Console.ForegroundColor = ConsoleColor.DarkRed;
            Console.WriteLine(name);
            Console.ResetColor();
        }

        /// <summary>
        /// Print menu options. Use an identificator to highlight the option that the user is currently on.
        /// </summary>
        /// <param name="options">An array of menu options.</param>
        /// <param name="selectedItem">Identificator that helps to determine which option to be highlighted.</param>
        private static void PrintMenuOptions(string[] options, int selectedItem)
        {
            for (int index = 0; index < options.Length; index++)
            {
                Console.SetCursorPosition((windowWidth - options[index].Length) / 2, 12 + index);
                if (index != selectedItem)
                {
                    Console.WriteLine(options[index]);
                }
                else
                {
                    Console.BackgroundColor = ConsoleColor.Yellow;
                    Console.ForegroundColor = ConsoleColor.Black;
                    Console.WriteLine(options[index]);
                    Console.ResetColor();
                }
            }
        }

        /// <summary>
        /// Navigate menu options. Use "Up" and "Down" arrow keys to navigate menu options. Use "Enter" key to select option.
        /// </summary>
        /// <returns>Identificator that shows the option that the user is currently on.</returns>
        private static int NavigateMenuOptions()
        {
            ConsoleKeyInfo keyPressed = Console.ReadKey(true);
            if (keyPressed.Key == ConsoleKey.UpArrow)
            {
                if (currentItem == 0)
                {
                    currentItem = menuItems.Length - 1;
                }
                else
                {
                    currentItem--;
                }
            }
            else if (keyPressed.Key == ConsoleKey.DownArrow)
            {
                if (currentItem == menuItems.Length - 1)
                {
                    currentItem = 0;
                }
                else
                {
                    currentItem++;
                }
            }
            else if (keyPressed.Key == ConsoleKey.Enter)
            {
                isChoiceMade = true;
            }

            return currentItem;
        }

        /// <summary>
        /// Call back main menu by clicking a single random key.
        /// </summary>
        private static void GetBackToMenu()
        {
            Console.SetCursorPosition(0, windowHeight - 1);
            Console.Write("Press any key to get back to main Menu.");
            Console.ReadKey();
            CallMenu();
        }

        /// <summary>
        /// Use identificator to understand which option was selected by the user. 
        /// Based on this choice it loads a specific part of the program.
        /// </summary>
        /// <param name="selectedItem">Identificator that points the selected option.</param>
        private static void GetUserChoice(int selectedItem)
        {
            Console.Clear();
            isChoiceMade = false;
            currentItem = 0;
            // The number of cases must be the same number as the number of menu options counting from zero.
            switch (selectedItem)
            {
                // New game
                case 0:
                    isChoiceMade = false;
                    Game.Gameplay();
                    break;
                // Highscores
                case 1:
                    //Print Score from file
                    ScoreEngine.PrintTopScores();
                    //Re-call Main menu
                    GetBackToMenu();
                    break;
                // Credits
                case 2:
                    // TO DO: Discuss with the team if this option is necessary.
                    Console.WriteLine("Coming soon...");
                    GetBackToMenu();
                    break;
                // Exit Game
                case 3:
                    // TO DO: Find a way to close the game and the app window.
                    Console.WriteLine("Thank you for playing \"Dangerous river\".");
                    break;
                // Invalid choice
                default:
                    Console.WriteLine("Error! Sorry!");
                    break;
            }
        }

        /// <summary>
        /// Print information how to navigate the menu and select options.
        /// </summary>
        private static void PrintHelp()
        {
            string navHelp = "Use \"Up\" and \"Down\" arrow keys to navigate.";
            string selectHelp = "Use \"Enter\" to select.";

            Console.SetCursorPosition(0, windowHeight - 2);
            Console.WriteLine(navHelp);
            Console.Write(selectHelp);
        }

        /// <summary>
        /// Print menu on the screen.
        /// </summary>
        public static void CallMenu()
        {
            Console.Clear();
            Console.CursorVisible = false;
            try
            {
                Console.SetWindowSize(windowWidth, windowHeight);
                Console.SetBufferSize(windowWidth, windowHeight);

                PrintHelp();
                PrintMenuTitle(menuTitle);
                while (isChoiceMade == false)
                {
                    PrintMenuOptions(menuItems, currentItem);
                    NavigateMenuOptions();
                }
                GetUserChoice(currentItem);
            }
            catch (ArgumentOutOfRangeException)
            {
                Console.WriteLine("Please, set your buffer and window height value to 30 and width size to 60.");
                Console.WriteLine("You can do this as follows: right click on Console title bar, Properties, Layout, Screen Buffer Size and Window Size.");
            }
        }
    }
}